home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1994 November: Tool Chest / Dev.CD Nov 94.toast / New System Software Extensions / OpenDoc A6 / OpenDoc Parts Framework / OPF / Examples / Draw / Sources / DrawSelection.cpp < prev    next >
Encoding:
Text File  |  1994-04-21  |  32.8 KB  |  1,249 lines  |  [TEXT/MPS ]

  1. //========================================================================================
  2. //
  3. //    File:                DrawSelection.cpp
  4. //    Release Version:    $ 1.0d1 $
  5. //
  6. //    Author:                Henri Lamiraux
  7. //    Creation Date:        3/28/94
  8. //
  9. //    Copyright:    © 1993, 1994 by Apple Computer, Inc., all rights reserved.
  10. //
  11. //========================================================================================
  12.  
  13. #ifndef DRAWSELECTION_H
  14. #include "DrawSelection.h"
  15. #endif
  16.  
  17. #ifndef DRAWPART_H
  18. #include "DrawPart.h"
  19. #endif
  20.  
  21. #ifndef DRAWFRAME_H
  22. #include "DrawFrame.h"
  23. #endif
  24.  
  25. #ifndef SHAPES_H
  26. #include "Shapes.h"
  27. #endif
  28.  
  29. #ifndef DRAWDEF_H
  30. #include "DrawDef.h"
  31. #endif
  32.  
  33. // ----- Framework Includes -----
  34.  
  35. #ifndef FWFRMING_H
  36. #include "FWFrming.h"
  37. #endif
  38.  
  39. #ifndef FWUTIL_H
  40. #include "FWUtil.h"
  41. #endif
  42.  
  43. #ifndef FWFACET_H
  44. #include "FWFacet.h"
  45. #endif
  46.  
  47. #ifndef FWEVENTH_H
  48. #include "FWEventH.h"
  49. #endif
  50.  
  51. #ifndef FWBORDER_H
  52. #include "FWBorder.h"
  53. #endif
  54.  
  55. // ----- OPF Foundation Includes -----
  56.  
  57. #ifndef BCSTOREU_H
  58. #include <BCStoreU.h>
  59. #endif
  60.  
  61. // ----- Graphic Includes -----
  62.  
  63. #ifndef FWGRAPHX_H
  64. #include "FWGraphx.h"
  65. #endif
  66.  
  67. // ----- OpenDoc Includes -----
  68.  
  69. #ifndef _SHAPE_
  70. #include <Shape.h>
  71. #endif
  72.  
  73. #ifndef _DRAGDROP_
  74. #include <DragDrop.h>
  75. #endif
  76.  
  77. #ifndef _XMPSESSN_
  78. #include <XMPSessM.h>
  79. #endif
  80.  
  81. #ifndef _STDPROPS_
  82. #include <StdProps.h>
  83. #endif
  84.  
  85. #ifndef _INFO_
  86. #include <Info.h>
  87. #endif
  88.  
  89. #ifndef _TRNSFORM_
  90. #include <Trnsform.h>
  91. #endif
  92.  
  93. #ifndef _LINK_
  94. #include <Link.h>
  95. #endif
  96.  
  97. #ifndef _LINKSRC_
  98. #include <LinkSrc.h>
  99. #endif
  100.  
  101. #ifndef _PLFMTYPE_
  102. #include <PlfmType.h>
  103. #endif
  104.  
  105. // ----- Macintosh Includes -----
  106.  
  107. #ifndef __DRAG__
  108. #include <Drag.h>
  109. #endif
  110.  
  111. #ifndef mathRoutinesIncludes
  112. #include <math routines.h>                // for ff()
  113. #endif
  114.  
  115. #pragma segment drawpart
  116.  
  117. //==============================================================================
  118. //    •• class CDrawSelection
  119. //==============================================================================
  120.  
  121. //------------------------------------------------------------------------------
  122. //    • CDrawSelection::CDrawSelection
  123. //------------------------------------------------------------------------------
  124.  
  125. CDrawSelection::CDrawSelection():
  126.     fDragRect(0,0,0,0)
  127. {
  128.     fDrawPart = NULL;
  129.     fUpdateShape = NULL;
  130.     fProxyShapeCount = 0;
  131.     fFrozenCount = 0;
  132.     fCount = 0;
  133.     fCollection = NULL;
  134.     fSelectionShape = NULL;
  135. }
  136.  
  137. //------------------------------------------------------------------------------
  138. //    • CDrawSelection::InitDrawSelection
  139. //------------------------------------------------------------------------------
  140.  
  141. void CDrawSelection::InitDrawSelection(CDrawPart* drawPart)
  142. {
  143.     InitSelection(drawPart, TRUE, TRUE);    // Allow both publish and subscrib
  144.     
  145.     fDrawPart = drawPart;
  146.     fCollection = new BC_TUnboundedCollection<CBaseShape*, BC_CUnmanaged>;
  147.     
  148.     fSelectionShape = ::NewXMPShape();
  149. }
  150.  
  151. //------------------------------------------------------------------------------
  152. //    • CDrawSelection::~CDrawSelection
  153. //------------------------------------------------------------------------------
  154.  
  155. CDrawSelection::~CDrawSelection()
  156. {    
  157.     delete fUpdateShape;
  158.     delete fSelectionShape;
  159.     delete fCollection;
  160. }
  161.  
  162. //------------------------------------------------------------------------------
  163. //    • CDrawSelection::WhichHandle
  164. //------------------------------------------------------------------------------
  165.  
  166. CBaseShape* CDrawSelection::WhichHandle(FW_CFacet* facet, const FW_CPoint& mouse, short& whichHandle) const
  167. {
  168.     whichHandle = 0;
  169.     
  170.     if (fCount != 0)
  171.     {
  172.         BC_TCollectionActiveIterator<CBaseShape*> ite(*fCollection);
  173.         CBaseShape *shape;
  174.         while (!ite.IsDone())
  175.         {
  176.             shape = *ite.CurrentItem();
  177.             whichHandle = shape->WhichHandle(facet, mouse);
  178.             if (whichHandle != 0)
  179.                 return shape;
  180.             ite.Next();
  181.         }
  182.     }
  183.     
  184.     return NULL;
  185. }
  186.  
  187. //------------------------------------------------------------------------------
  188. //    • CDrawSelection::DrawSelectionHandles
  189. //------------------------------------------------------------------------------
  190.  
  191. void CDrawSelection::DrawSelectionHandles(FW_CFacet* facet, FW_Boolean turOn)
  192. {
  193.     BC_TCollectionActiveIterator<CBaseShape*> ite(*fCollection);
  194.     while (!ite.IsDone())
  195.     {
  196.         (*ite.CurrentItem())->DrawShapeHandles(facet, turOn);    
  197.         ite.Next();
  198.     }
  199. }
  200.  
  201. //------------------------------------------------------------------------------
  202. //    • CDrawSelection::DrawAllHandles
  203. //------------------------------------------------------------------------------
  204.  
  205. void CDrawSelection::DrawAllHandles(FW_CFrame* frame, FW_Boolean turOn)
  206. {
  207.     if (fCount != 0)
  208.     {
  209.         FW_CFrameFacetIterator ite(frame);
  210.         FW_CFacet* facet;
  211.         while (!ite.IsDone())
  212.         {
  213.             facet = ite.CurrentItem();
  214.             FW_CGraphicContext gc(*facet);
  215.             DrawSelectionHandles(facet, turOn);
  216.             ite.Next();
  217.         }
  218.     }
  219. }
  220.  
  221. //------------------------------------------------------------------------------
  222. //    • CDrawSelection::DrawHandles
  223. //------------------------------------------------------------------------------
  224.  
  225. void CDrawSelection::DrawHandles(CBaseShape* shape, FW_Boolean turOn)
  226. {
  227.     FW_CPartFrameIterator ite(fDrawPart, fDrawPart->GetMainPresentation());
  228.     FW_CFrame* frame;
  229.     while (!ite.IsDone())
  230.     {
  231.         frame = ite.CurrentItem();
  232.         if (frame->IsActive())
  233.         {
  234.             FW_CFrameFacetIterator i(frame);            
  235.             FW_CFacet* facet;
  236.             while (!i.IsDone())
  237.             {
  238.                 facet = i.CurrentItem();
  239.                 FW_CGraphicContext gc(*facet);
  240.                 shape->DrawShapeHandles(facet, turOn);
  241.                 i.Next();
  242.             }
  243.         }
  244.         ite.Next();
  245.     }
  246. }
  247.  
  248. //------------------------------------------------------------------------------
  249. //    • CDrawSelection::CloseSelection
  250. //------------------------------------------------------------------------------
  251.  
  252. void CDrawSelection::CloseSelection()
  253. {
  254.     CBaseShape *shape;    
  255.     while (!fCollection->IsEmpty())
  256.     {
  257.         shape = fCollection->First();
  258.         DoRemove(shape);
  259.         DrawHandles(shape, FALSE);        // turn off
  260.     }
  261.  
  262.     CalcDragRect();
  263.     CalcUpdateShape();
  264. }
  265.  
  266. //------------------------------------------------------------------------------
  267. //    • CDrawSelection::AddToSelection
  268. //------------------------------------------------------------------------------
  269.  
  270. void CDrawSelection::AddToSelection(CBaseShape* newSelection, FW_Boolean drawHandles)
  271. {                
  272.     if (newSelection != NULL)
  273.     {
  274.         DoAdd(newSelection);
  275.         if (drawHandles)
  276.             DrawHandles(newSelection, TRUE);    // Turn on    
  277.     }        
  278.             
  279.     CalcDragRect();
  280.     CalcUpdateShape();
  281. }
  282.  
  283. //------------------------------------------------------------------------------
  284. //    • CDrawSelection::RemoveFromSelection
  285. //------------------------------------------------------------------------------
  286.  
  287. void CDrawSelection::RemoveFromSelection(CBaseShape* shape, FW_Boolean drawHandles)
  288. {                
  289.     if (shape != NULL)
  290.     {
  291.         DoRemove(shape);
  292.         if (drawHandles)
  293.             DrawHandles(shape, FALSE);        // Turn Off
  294.     }        
  295.         
  296.     CalcDragRect();
  297.     CalcUpdateShape();
  298. }
  299.  
  300. //------------------------------------------------------------------------------
  301. //    • CDrawSelection::DoAdd
  302. //------------------------------------------------------------------------------
  303.  
  304. void CDrawSelection::DoAdd(CBaseShape *shape)
  305. {
  306.     shape->SelectShape(TRUE);
  307.     fCollection->Append(shape);
  308.     fCount++;
  309.     if (shape->GetShapeType() == kProxyShape)
  310.         fProxyShapeCount++;
  311.     if (shape->IsFrozen())
  312.         fFrozenCount++;
  313. }
  314.  
  315. //------------------------------------------------------------------------------
  316. //    • CDrawSelection::DoRemove
  317. //------------------------------------------------------------------------------
  318.  
  319. void CDrawSelection::DoRemove(CBaseShape *shape)
  320. {
  321.     shape->SelectShape(FALSE);
  322.     fCollection->Remove(fCollection->Location(shape));
  323.     fCount--;
  324.     if (shape->GetShapeType() == kProxyShape)
  325.         fProxyShapeCount--;
  326.     if (shape->IsFrozen())
  327.         fFrozenCount--;
  328. }
  329.  
  330. //------------------------------------------------------------------------------
  331. //    • CDrawSelection::DoClear
  332. //------------------------------------------------------------------------------
  333.  
  334. FW_Boolean CDrawSelection::DoClear()
  335. {
  336.     CBaseShape *shape;
  337.     while (!fCollection->IsEmpty())
  338.     {
  339.         shape = fCollection->First();
  340.         DoRemove(shape);                // Remove from Selection list
  341.         fDrawPart->DeleteShape(shape);    // Remove from shape list
  342.     }
  343.     
  344.     fDrawPart->ClipEmbeddedFrames(fDrawPart->GetMainPresentation());
  345.     fDrawPart->InvalidateAllFrames(fDrawPart->GetMainPresentation(), NULL, fUpdateShape);
  346.     
  347.     CalcDragRect();
  348.     CalcUpdateShape();
  349.     
  350.     return TRUE;
  351. }
  352.  
  353. //------------------------------------------------------------------------------
  354. //    • CDrawSelection::SelectAll
  355. //------------------------------------------------------------------------------
  356.  
  357. void CDrawSelection::SelectAll()
  358. {                
  359.     DrawAllHandles(fDrawPart->GetActiveFrame(), FALSE);
  360.  
  361.     BC_TCollectionActiveIterator<CBaseShape*> ite(*fDrawPart->GetShapeList());
  362.     CBaseShape *shape;
  363.     while (!ite.IsDone())
  364.     {
  365.         shape = *ite.CurrentItem();
  366.         if (!shape->IsSelected())
  367.             DoAdd(shape);
  368.         ite.Next();
  369.     }
  370.     
  371.     DrawAllHandles(fDrawPart->GetActiveFrame(), TRUE);
  372.  
  373.     CalcDragRect();
  374.     CalcUpdateShape();
  375.     
  376.     fDrawPart->SetTool(kSelectTool);
  377. }
  378.  
  379. //------------------------------------------------------------------------------
  380. //    • CDrawSelection::IsEmpty
  381. //------------------------------------------------------------------------------
  382.  
  383. FW_Boolean CDrawSelection::IsEmpty() const
  384. {    
  385.     return fCount == 0;
  386. }
  387.  
  388. //------------------------------------------------------------------------------
  389. //    • CDrawSelection::IsSelectionOnlyOneProxyRun
  390. //------------------------------------------------------------------------------
  391.  
  392. FW_CProxyRun* CDrawSelection::IsSelectionOnlyOneProxyRun() const
  393. {
  394.     if (fCount == 1 && fProxyShapeCount == 1)
  395.     {
  396.         return ((CProxyShape*)fCollection->First())->GetProxyRun();
  397.     }
  398.     
  399.     return NULL;
  400. }
  401.  
  402. //------------------------------------------------------------------------------
  403. //    • CDrawSelection::ExternalizeSelection
  404. //------------------------------------------------------------------------------
  405.  
  406. void CDrawSelection::ExternalizeSelection(XMPStorageUnit* storageUnit, FW_CFrame* commandFrame, XMPCloneKind cloneKind)
  407. {
  408.     storageUnit->AddProperty(kXMPPropContents)->AddValue(GetPart()->GetContentPropertyValueType());
  409.     
  410.     // ----- Write number of shapes -----
  411.     storageUnit->SetValue(sizeof(fCount), (XMPValue)&fCount);
  412.     
  413.     // ----- Write top left offset -----
  414.     XMPCoordinate coordinate = -fDragRect.left;
  415.     storageUnit->SetValue(sizeof(coordinate), (XMPValue)&coordinate);
  416.     coordinate = -fDragRect.top;
  417.     storageUnit->SetValue(sizeof(coordinate), (XMPValue)&coordinate);
  418.     
  419.     // ----- Write out the contents of the selection -----
  420.     BC_TCollectionActiveIterator<CBaseShape*> ite(*fCollection);
  421.     while (!ite.IsDone())
  422.     {
  423.         (*ite.CurrentItem())->CloneTo(storageUnit, commandFrame, cloneKind);
  424.         ite.Next();
  425.     }
  426. }
  427.  
  428. //------------------------------------------------------------------------------
  429. //    • CDrawSelection::InternalizeSelection
  430. //------------------------------------------------------------------------------
  431.  
  432. FW_Boolean CDrawSelection::InternalizeSelection(XMPStorageUnit* storageUnit, XMPCloneKind cloneKind)
  433. {
  434.     if (storageUnit->Exists(kXMPPropContents, GetPart()->GetContentPropertyValueType(), 0))
  435.     {
  436.         // ----- Close First the current selection -----
  437.         CloseSelection();
  438.         
  439.         // ----- Focus on content property -----
  440.         storageUnit->Focus(kXMPPropContents, kXMPPosUndefined, 
  441.                                GetPart()->GetContentPropertyValueType(), (XMPValueIndex)0, kXMPPosUndefined);
  442.     
  443.         // ----- Read number of shapes -----
  444.         unsigned long count;
  445.         storageUnit->GetValue(sizeof(count), (XMPValue)&count);
  446.     
  447.         // ----- Read top left offset -----
  448.         XMPCoordinate xTopLeft, yTopLeft;
  449.         storageUnit->GetValue(sizeof(xTopLeft), (XMPValue)&xTopLeft);
  450.         storageUnit->GetValue(sizeof(yTopLeft), (XMPValue)&yTopLeft);
  451.         
  452.         // ----- Then read in the new selection -----
  453.         CBaseShape *after = NULL;
  454.         for (unsigned short i = 0; i<count; i++)
  455.         {
  456.             unsigned short shapeType;
  457.             CBaseShape* theShape = NULL;
  458.             storageUnit->GetValue(sizeof(unsigned short), (XMPValue)&shapeType);    
  459.             theShape = fDrawPart->NewShape(shapeType);
  460.             
  461.             if (theShape)
  462.             {
  463.                 theShape->CloneFrom(fDrawPart, storageUnit, cloneKind);
  464.                 
  465.                 if (after)
  466.                     fDrawPart->AddShapeAfter(after, theShape);
  467.                 else
  468.                     fDrawPart->AddShape(theShape);
  469.                 after = theShape;
  470.                 
  471.                 this->AddToSelection(theShape, FALSE);
  472.             }
  473.         }
  474.     
  475.         this->OffsetSelection(xTopLeft, yTopLeft);
  476.  
  477.         return TRUE;
  478.     }
  479.     
  480.     return FALSE;
  481. }
  482.  
  483. //------------------------------------------------------------------------------
  484. //    • CDrawSelection::EmbedSelection
  485. //------------------------------------------------------------------------------
  486.  
  487. FW_Boolean CDrawSelection::EmbedSelection(XMPPart* xmpPart, XMPShape* frameShape)
  488. {
  489.     CloseSelection();
  490.     
  491.     FW_CRect shapeRect;
  492.     if (frameShape)
  493.     {
  494.         frameShape->GetBoundingBox(&shapeRect);
  495.         shapeRect.Offset(ff(-shapeRect.left), ff(-shapeRect.top));
  496.     }
  497.     else
  498.     {
  499.         shapeRect.Set(ff(0), ff(0), ff(80), ff(80));
  500.     }
  501.     
  502.     CProxyShape *proxyShape = fDrawPart->NewProxyShape(xmpPart, shapeRect, FALSE);
  503.     
  504.     AddToSelection(proxyShape, FALSE);
  505.     
  506.     return TRUE;
  507. }
  508.  
  509. //------------------------------------------------------------------------------
  510. //    • CDrawSelection::DoPaste
  511. //------------------------------------------------------------------------------
  512.  
  513. FW_Boolean CDrawSelection::DoPaste()
  514. {
  515.     FW_Boolean result = FW_CSelection::DoPaste();
  516.     
  517.     if (result)
  518.         AdjustSelectionAfterPaste();
  519.     
  520.     return result;
  521. }
  522.  
  523. //------------------------------------------------------------------------------
  524. //    • CDrawSelection::DoPasteWithLink
  525. //------------------------------------------------------------------------------
  526.  
  527. FW_Boolean CDrawSelection::DoPasteWithLink()
  528. {
  529.     FW_Boolean result = FW_CSelection::DoPasteWithLink();
  530.     
  531.     if (result)
  532.         AdjustSelectionAfterPaste();
  533.     
  534.     return result;
  535. }
  536.  
  537. //------------------------------------------------------------------------------
  538. //    • CDrawSelection::InsertNewPart
  539. //------------------------------------------------------------------------------
  540.  
  541. FW_Boolean CDrawSelection::InsertNewPart()
  542. {
  543.     FW_Boolean result = FW_CSelection::InsertNewPart();
  544.     
  545.     if (result)
  546.         AdjustSelectionAfterPaste();
  547.     
  548.     return result;
  549. }
  550.  
  551. //------------------------------------------------------------------------------
  552. //    • CDrawSelection::AdjustSelectionAfterPaste
  553. //------------------------------------------------------------------------------
  554.  
  555. void CDrawSelection::AdjustSelectionAfterPaste()
  556. {
  557.     fDrawPart->SetTool(kSelectTool);
  558.     
  559.     fDrawPart->InvalidateAllFrames(fDrawPart->GetMainPresentation(), NULL, fUpdateShape);
  560. }
  561.  
  562. //------------------------------------------------------------------------------
  563. //    • CDrawSelection::DoDroppedInSameFrame
  564. //------------------------------------------------------------------------------
  565.  
  566. FW_Boolean CDrawSelection::DoDroppedInSameFrame(XMPStorageUnit* dropSU, FW_CFacet* facet,
  567.                                                 const FW_CPoint& originPoint, const FW_CPoint& dropPoint)
  568. {
  569.     FW_UNUSED(dropSU);
  570.     
  571.     FW_CPoint delta = dropPoint - originPoint;
  572.     if (delta != FW_CPoint(0,0))
  573.     {
  574.         facet->InvalidateAllFacets(fUpdateShape, FALSE);
  575.         OffsetSelection(delta.x, delta.y);
  576.         facet->InvalidateAllFacets(fUpdateShape, FALSE);
  577.     }
  578.     
  579.     return TRUE;
  580. }
  581.  
  582. //------------------------------------------------------------------------------
  583. //    • CDrawSelection::DoDrop
  584. //------------------------------------------------------------------------------
  585.  
  586. FW_Boolean CDrawSelection::DoDrop(XMPStorageUnit* dropSU, FW_CFacet* facet, const FW_CPoint& originPoint, const FW_CPoint& dropPoint)
  587. {
  588.     CloseSelection();
  589.     
  590.     FW_Boolean result = FW_CSelection::DoDrop(dropSU, facet, originPoint, dropPoint);
  591.     
  592.     if (result)
  593.     {
  594.         fDrawPart->SetTool(kSelectTool);
  595.         
  596.         FW_CPoint newOffset = dropPoint;
  597.         FW_CPoint frameOffset(facet->GetWindowFrameTransform()->GetQDOffset());
  598.         
  599.         newOffset -= frameOffset;
  600.         newOffset -= originPoint;
  601.         
  602.         FW_CRect box;
  603.         fUpdateShape->GetBoundingBox(&box);
  604.         FW_CPoint currentOffset = box.TopLeft();
  605.         OffsetSelection(-currentOffset.x + newOffset.x, -currentOffset.y + newOffset.y);
  606.         
  607.         // ----- Invalidate -----
  608.         fDrawPart->InvalidateAllFrames(fDrawPart->GetMainPresentation(), NULL, fUpdateShape);
  609.     }
  610.     
  611.     return result;
  612. }
  613.  
  614. //------------------------------------------------------------------------------
  615. //    • CDrawSelection::DragFeedback
  616. //------------------------------------------------------------------------------
  617.  
  618. void CDrawSelection::DragFeedback(FW_PlatformRegion dragRgn, short xDelta, short yDelta)
  619. {
  620.     ::OffsetRgn(dragRgn, xDelta, yDelta);
  621.     ::PaintRgn(dragRgn);
  622.     ::OffsetRgn(dragRgn, -xDelta, -yDelta);
  623. }
  624.  
  625. //------------------------------------------------------------------------------
  626. //    • CDrawSelection::Resize
  627. //------------------------------------------------------------------------------
  628.  
  629. void CDrawSelection::Resize(FW_CGraphicContext* gc, short whichHandle, const FW_CPoint& firstPoint, XMPEventData event)
  630. {    
  631.     if (!::WaitMouseMoved(event->where))
  632.         return;
  633.     
  634.     CBaseShape* anchorShape = GetAnchorShape();
  635.     
  636.     FW_CPoint handleCenter;
  637.     anchorShape->GetHandleCenter(whichHandle, &handleCenter);
  638.     anchorShape->DrawHandle(whichHandle);    // erase handle
  639.     
  640.     // ----- Calcul delta between the mouse click and the
  641.     // ----- handle center
  642.     FW_CPoint delta = firstPoint - handleCenter;
  643.     
  644.     FW_CPoint currentLoc;
  645.     FW_CPoint prevLoc = handleCenter;
  646.  
  647.     FW_Boolean firstMove = TRUE;
  648.     
  649.     XMPCoordinate penSize = anchorShape->GetPenSize();
  650.  
  651.     FW_CInk trackInk(FW_kRGBBlack, FW_kRGBWhite, FW_kXOr);
  652.     FW_CStyle trackStyle(penSize);
  653.  
  654.     FW_CRect mapRect = anchorShape->GetBoundingBox();
  655.     FW_CRect orgRect = mapRect;
  656.     FW_Boolean eraseFlag = FALSE;
  657.     FW_Boolean stillDown = TRUE;
  658.     
  659.     while (stillDown)
  660.     {
  661.         FW_SPlatformPoint qdLoc;
  662.         ::GetMouse(&qdLoc);    
  663.         currentLoc = qdLoc;
  664.         currentLoc -= delta;
  665.         
  666.         if (prevLoc != currentLoc)
  667.         {
  668.             if (eraseFlag)
  669.                 anchorShape->ResizeFeedback(gc, trackInk, trackStyle, orgRect, mapRect);        // erase
  670.             
  671.             mapRect = orgRect;
  672.             CalcMapRect(whichHandle, currentLoc, penSize, &mapRect);
  673.             
  674.             anchorShape->ResizeFeedback(gc, trackInk, trackStyle, orgRect, mapRect);            // draw
  675.             
  676.             eraseFlag = TRUE;                
  677.             prevLoc = currentLoc;
  678.         }
  679.         
  680.         stillDown = ::StillDown(); 
  681.     }
  682.     
  683.     if (eraseFlag)
  684.         anchorShape->ResizeFeedback(gc, trackInk, trackStyle, orgRect, mapRect);                // Erase
  685.         
  686.     ::PenNormal();
  687.     
  688.     if (firstPoint != currentLoc)
  689.     {
  690.         FW_CFacet* facet = FW_CFacet::XMPtoFWFacet(gc->GetXMPFacet());
  691.         
  692.         facet->InvalidateAllFacets(fUpdateShape, FALSE);
  693.         MapSelection(orgRect, mapRect);
  694.         facet->InvalidateAllFacets(fUpdateShape, FALSE);
  695.         
  696.         // ----- Clip all embedding frames -----
  697.         ((FW_CEmbeddingPart*)facet->GetFrame()->GetPart())->ClipEmbeddedFrames(facet->GetFrame()->GetIdentifier());
  698.         
  699.         SelectionChanged();
  700.     }
  701.     else
  702.     {
  703.         anchorShape->DrawHandle(whichHandle);    // redraw the handle
  704.     }
  705. }
  706.  
  707. //------------------------------------------------------------------------------
  708. //    • CDrawSelection::CalcMapRect
  709. //------------------------------------------------------------------------------
  710.  
  711. void CDrawSelection::CalcMapRect(short whichHandle, const FW_CPoint& currentPos, XMPCoordinate penSize, FW_CRect* mapRect)
  712. {
  713.     switch (whichHandle)
  714.     {
  715.         case kInTopLeftCorner:
  716.             mapRect->left = currentPos.x;
  717.             mapRect->top = currentPos.y;
  718.             break;
  719.         case kInTopRightCorner:
  720.             mapRect->right = currentPos.x+1;
  721.             mapRect->top = currentPos.y;
  722.             break;
  723.         case kInBottomLeftCorner:
  724.             mapRect->left = currentPos.x;
  725.             mapRect->bottom = currentPos.y+1;
  726.             break;
  727.         case kInBottomRightCorner:
  728.             mapRect->right = currentPos.x+1;
  729.             mapRect->bottom = currentPos.y+1;
  730.             break;
  731.     }
  732.     
  733.     if (mapRect->left > mapRect->right)
  734.     {
  735.         switch (whichHandle)
  736.         {
  737.             case 1:
  738.             case 3:
  739.                 mapRect->right -= penSize;
  740.                 break;
  741.             case 2:
  742.             case 4:
  743.                 mapRect->left += penSize;
  744.                 break;
  745.         }        
  746.     }
  747.     if (mapRect->top > mapRect->bottom)
  748.     {
  749.         switch (whichHandle)
  750.         {
  751.             case 1:
  752.             case 2:
  753.                 mapRect->bottom -= penSize;
  754.                 break;
  755.             case 3:
  756.             case 4:
  757.                 mapRect->top += penSize;
  758.                 break;
  759.         }        
  760.     }
  761. }
  762.  
  763. //------------------------------------------------------------------------------
  764. //    • CDrawSelection::CalcDragRect
  765. //------------------------------------------------------------------------------
  766.  
  767. void CDrawSelection::CalcDragRect()
  768. {
  769.     fDragRect.Clear();
  770.     
  771.     if (fCount == 0)
  772.         return;
  773.         
  774.     BC_TCollectionActiveIterator<CBaseShape*> ite(*fCollection);
  775.     FW_Boolean first = TRUE;
  776.     while (!ite.IsDone())
  777.     {
  778.         FW_CRect tempRect = (*ite.CurrentItem())->GetBoundingBox();
  779.         if (first)
  780.             fDragRect = tempRect;
  781.         else
  782.             fDragRect |= tempRect;
  783.         first = FALSE;
  784.         ite.Next();
  785.     }
  786. }
  787.  
  788. //------------------------------------------------------------------------------
  789. //    • CDrawSelection::CalcDragRgn
  790. //------------------------------------------------------------------------------
  791.  
  792. XMPRgnHandle CDrawSelection::CalcDragRgn(FW_CFacet* facet)
  793. {
  794.     FW_CGraphicContext gc(*facet);
  795.     
  796.     CBaseShape* anchorShape = GetAnchorShape();
  797.     XMPRgnHandle dragRgn = ::NewRgn();
  798.  
  799.     FW_PlatformRegion tempRgn = ::NewRgn();
  800.  
  801.     if (fCount > 1)
  802.     {
  803.         FW_SPlatformRect qdRect = fDragRect;
  804.         ::RectRgn(dragRgn, &qdRect);
  805.         ::CopyRgn(dragRgn, tempRgn);
  806.         ::InsetRgn(tempRgn, 1, 1);
  807.         ::DiffRgn(dragRgn, tempRgn, dragRgn);
  808.     }
  809.     
  810.     anchorShape->GetDragRgn(&gc, tempRgn);
  811.     ::UnionRgn(dragRgn, tempRgn, dragRgn);
  812.     
  813.     ::DisposeRgn(tempRgn);
  814.         
  815.     return dragRgn;
  816. }
  817.  
  818. //------------------------------------------------------------------------------
  819. //    • CDrawSelection::CalcUpdateShape
  820. //------------------------------------------------------------------------------
  821.  
  822. void CDrawSelection::CalcUpdateShape()
  823. {
  824.     delete fUpdateShape;
  825.     fUpdateShape = ::NewXMPShape();
  826.     
  827.     if (fCount == 0)
  828.         return;
  829.  
  830.     BC_TCollectionActiveIterator<CBaseShape*> ite(*fCollection);
  831.     XMPShape* tempShape = ::NewXMPShape();
  832.     while (!ite.IsDone())
  833.     {
  834.         (*ite.CurrentItem())->GetUpdateShape(tempShape);
  835.         fUpdateShape->Union(tempShape);
  836.         ite.Next();
  837.     }
  838.     delete tempShape;
  839. }
  840.  
  841. //------------------------------------------------------------------------------
  842. //    • CDrawSelection::MapSelection
  843. //------------------------------------------------------------------------------
  844.  
  845. void CDrawSelection::MapSelection(const FW_CRect& srcRect, const FW_CRect& dstRect)
  846. {
  847.     BC_TCollectionActiveIterator<CBaseShape*> ite(*fCollection);
  848.     while (!ite.IsDone())
  849.     {
  850.         (*ite.CurrentItem())->MapShape(srcRect, dstRect);
  851.         ite.Next();
  852.     }
  853.     
  854.     fDrawPart->ClipEmbeddedFrames(fDrawPart->GetMainPresentation());
  855.     
  856.     CalcDragRect();
  857.     CalcUpdateShape();
  858. }
  859.  
  860. //------------------------------------------------------------------------------
  861. //    • CDrawSelection::OffsetSelection
  862. //------------------------------------------------------------------------------
  863.  
  864. void CDrawSelection::OffsetSelection(XMPCoordinate xDelta, XMPCoordinate yDelta)
  865. {
  866.     BC_TCollectionActiveIterator<CBaseShape*> ite(*fCollection);
  867.     while (!ite.IsDone())
  868.     {
  869.         (*ite.CurrentItem())->OffsetShape(xDelta, yDelta);
  870.         ite.Next();
  871.     }
  872.  
  873.     fDrawPart->ClipEmbeddedFrames(fDrawPart->GetMainPresentation());
  874.     
  875.     CalcDragRect();
  876.     CalcUpdateShape();
  877. }
  878.  
  879. //------------------------------------------------------------------------------
  880. //    • CDrawSelection::SelectWithRectangle
  881. //------------------------------------------------------------------------------
  882.  
  883. void CDrawSelection::SelectWithRectangle(FW_CFacet* facet, const FW_CPoint& anchorPoint, XMPEventData event)
  884. {
  885.     CRectShape rectShape;    // Create a rect shape on the stack
  886.  
  887.     char framePat[8] = {0xCC, 0x66, 0x33, 0x99, 0xCC, 0x66, 0x33, 0x99};
  888.     FW_CStyle trackStyle(ff(1), framePat);
  889.     
  890.     FW_CGraphicContext gc(*facet);
  891.     if (rectShape.Track(&gc, trackStyle, anchorPoint, event))
  892.     {
  893.         FW_Boolean isShift = IsShiftKeyPressed();
  894.         FW_CRect selectRect = rectShape.GetBoundingBox();
  895.         BC_TCollectionActiveIterator<CBaseShape*> ite(*fDrawPart->GetShapeList());
  896.         CBaseShape *shape;
  897.         while (!ite.IsDone())
  898.         {
  899.             shape = *ite.CurrentItem();
  900.             if (shape->InSelectionRect(selectRect))
  901.             {
  902.                 if (shape->IsSelected())
  903.                 {
  904.                     if (isShift)
  905.                     {
  906.                         DoRemove(shape);
  907.                         DrawHandles(shape, FALSE);        // Turn Off
  908.                     }
  909.                 }
  910.                 else
  911.                 {
  912.                     DoAdd(shape);
  913.                     DrawHandles(shape, TRUE);    // Turn on    
  914.                 }
  915.             }
  916.             else if (shape->IsSelected() && !isShift)
  917.             {
  918.                 DoRemove(shape);
  919.                 DrawHandles(shape, FALSE);        // Turn Off
  920.             }
  921.             ite.Next();
  922.         }            
  923.         CalcDragRect();
  924.         CalcUpdateShape();
  925.     }
  926.     else
  927.     {
  928.         CloseSelection();
  929.     }
  930. }
  931.  
  932. //------------------------------------------------------------------------------
  933. //    • CDrawSelection::ChangeSelectionPenSize
  934. //------------------------------------------------------------------------------
  935.  
  936. void CDrawSelection::ChangeSelectionPenSize(XMPCoordinate newPenSize)
  937. {
  938.     BC_TCollectionActiveIterator<CBaseShape*> ite(*fCollection);
  939.     CBaseShape* shape;
  940.     while (!ite.IsDone())
  941.     {
  942.         shape = *ite.CurrentItem();
  943.         FW_CStyle newStyle = shape->GetPenStyle()->Copy();
  944.         newStyle->SetPenSize(newPenSize);
  945.         shape->SetPenStyle(newStyle);
  946.         this->RedrawShape(shape);
  947.         ite.Next();
  948.     }
  949.     
  950.     fDrawPart->ClipEmbeddedFrames(fDrawPart->GetMainPresentation());
  951.  
  952.     SelectionChanged();
  953. }
  954.  
  955. //------------------------------------------------------------------------------
  956. //    • CDrawSelection::ChangeSelectionFillColor
  957. //------------------------------------------------------------------------------
  958.  
  959. void CDrawSelection::ChangeSelectionFillColor(const FW_CColor& color)
  960. {
  961.     BC_TCollectionActiveIterator<CBaseShape*> ite(*fCollection);
  962.     CBaseShape* shape;
  963.     while (!ite.IsDone())
  964.     {
  965.         shape = *ite.CurrentItem();
  966.         FW_CInk newInk = shape->GetBrushInk()->Copy();
  967.         newInk->SetForeColor(color);
  968.         shape->SetBrushInk(newInk);
  969.         this->RedrawShape(shape);
  970.         ite.Next();
  971.     }
  972.     
  973.     SelectionChanged();
  974. }
  975.  
  976. //------------------------------------------------------------------------------
  977. //    • CDrawSelection::ChangeSelectionPenColor
  978. //------------------------------------------------------------------------------
  979.  
  980. void CDrawSelection::ChangeSelectionPenColor(const FW_CColor& color)
  981. {
  982.     BC_TCollectionActiveIterator<CBaseShape*> ite(*fCollection);
  983.     CBaseShape* shape;
  984.     while (!ite.IsDone())
  985.     {
  986.         shape = *ite.CurrentItem();
  987.         FW_CInk newInk = shape->GetPenInk()->Copy();
  988.         newInk->SetForeColor(color);
  989.         shape->SetPenInk(newInk);
  990.         this->RedrawShape(shape);
  991.         ite.Next();
  992.     }
  993.     
  994.     SelectionChanged();
  995. }
  996.  
  997. //------------------------------------------------------------------------------
  998. //    • CDrawSelection::ChangeSelectionFillFrame
  999. //------------------------------------------------------------------------------
  1000.  
  1001. void CDrawSelection::ChangeSelectionFillFrame(unsigned short newFillFrame)
  1002. {
  1003.     BC_TCollectionActiveIterator<CBaseShape*> ite(*fCollection);
  1004.     CBaseShape* shape;
  1005.     while (!ite.IsDone())
  1006.     {
  1007.         shape = *ite.CurrentItem();
  1008.         shape->SetFrameFillStyle(newFillFrame);
  1009.         this->RedrawShape(shape);
  1010.         ite.Next();
  1011.     }
  1012.     
  1013.     fDrawPart->ClipEmbeddedFrames(fDrawPart->GetMainPresentation());
  1014.     
  1015.     SelectionChanged();
  1016. }
  1017.  
  1018. //------------------------------------------------------------------------------
  1019. //    • CDrawSelection::RedrawShape
  1020. //------------------------------------------------------------------------------
  1021.  
  1022. void CDrawSelection::RedrawShape(CBaseShape *shape)
  1023. {
  1024.     XMPShape* invalidShape = ::NewXMPShape();
  1025.     shape->GetUpdateShape(invalidShape);
  1026.     fDrawPart->InvalidateAllFrames(fDrawPart->GetMainPresentation(), NULL, invalidShape);
  1027.     delete invalidShape;
  1028. }
  1029.  
  1030. //------------------------------------------------------------------------------
  1031. //    • CDrawSelection::SetFrozen
  1032. //------------------------------------------------------------------------------
  1033.  
  1034. void CDrawSelection::SetFrozen(FW_Boolean state)
  1035. {
  1036.     BC_TCollectionActiveIterator<CBaseShape*> ite(*fCollection);
  1037.     CBaseShape* shape;
  1038.     while (!ite.IsDone())
  1039.     {
  1040.         shape = *ite.CurrentItem();
  1041.         if (shape->SetFrozen(state))
  1042.         {
  1043.             state ? fFrozenCount++ : fFrozenCount--;
  1044.         }
  1045.         ite.Next();
  1046.     }
  1047. }
  1048.  
  1049. //------------------------------------------------------------------------------
  1050. //    • CDrawSelection::NewPublishLink
  1051. //------------------------------------------------------------------------------
  1052.  
  1053. FW_CPublishLink* CDrawSelection::NewPublishLink(XMPChangeID changeID)
  1054. {
  1055.     return new CDrawPublishLink(changeID, this);
  1056. }
  1057.  
  1058. //------------------------------------------------------------------------------
  1059. //    • CDrawSelection::NewSubscribLink
  1060. //------------------------------------------------------------------------------
  1061.  
  1062. FW_CSubscribLink* CDrawSelection::NewSubscribLink(XMPLink *xmpLink)
  1063. {
  1064.     return new CDrawSubscribLink(xmpLink, this);
  1065. }
  1066.  
  1067. //------------------------------------------------------------------------------
  1068. //    • CDrawSelection::SelectionChanged
  1069. //------------------------------------------------------------------------------
  1070.  
  1071. void CDrawSelection::SelectionChanged()
  1072. {
  1073.     BC_TDynamicCollection<CDrawPublishLink*, BC_CUnmanaged> temp(5);    // Assume an average of 5 shapes
  1074.     BC_TCollectionActiveIterator<CDrawPublishLink*> tempIte(temp);
  1075.     
  1076.     BC_TCollectionActiveIterator<CBaseShape*> ite(*fCollection);
  1077.     CBaseShape* shape;
  1078.     while (!ite.IsDone())
  1079.     {
  1080.         shape = *ite.CurrentItem();
  1081.         if (shape->IsPublished())
  1082.         {
  1083.             FW_Boolean add = TRUE;
  1084.             tempIte.Reset();
  1085.             CDrawPublishLink* link;
  1086.             while (!tempIte.IsDone())
  1087.             {
  1088.                 link = *tempIte.CurrentItem();
  1089.                 if (shape->GetPublishLink() == link)
  1090.                 {
  1091.                     add = FALSE;
  1092.                     break;
  1093.                 }
  1094.                 tempIte.Next();
  1095.             }
  1096.             if (add)
  1097.                 temp.Append(shape->GetPublishLink());
  1098.         }
  1099.         ite.Next();
  1100.     }
  1101.     
  1102.     tempIte.Reset();
  1103.     while (!tempIte.IsDone())
  1104.     {
  1105.         (*tempIte.CurrentItem())->ContentChanged(fDrawPart->GetSession()->UniqueChangeID());
  1106.         tempIte.Next();
  1107.     }
  1108. }
  1109.  
  1110. //------------------------------------------------------------------------------
  1111. //    • CDrawSelection::IsSelectionPublishable
  1112. //------------------------------------------------------------------------------
  1113. //    We don't allow linking if one of the shape is already published
  1114.  
  1115. FW_Boolean CDrawSelection::IsSelectionPublishable()
  1116. {
  1117.     FW_Boolean result = TRUE;
  1118.     
  1119.     BC_TCollectionActiveIterator<CBaseShape*> ite(*fCollection);
  1120.     while (!ite.IsDone())
  1121.     {
  1122.         if ((*ite.CurrentItem())->IsPublished())
  1123.         {
  1124.             result = FALSE;
  1125.             break;
  1126.         }
  1127.         ite.Next();
  1128.     }
  1129.     
  1130.     return result;
  1131. }
  1132.  
  1133. //------------------------------------------------------------------------------
  1134. //    • CDrawSelection::GetSelectionShape
  1135. //------------------------------------------------------------------------------
  1136.  
  1137. XMPShape* CDrawSelection::GetSelectionShape()
  1138. {
  1139.     FW_CRect selectionRect(fDragRect);
  1140.     selectionRect.Offset(-selectionRect.left, -selectionRect.top);
  1141.     fSelectionShape->SetRectangle(&selectionRect);
  1142.     return fSelectionShape;
  1143. }
  1144.  
  1145. //==============================================================================
  1146. //    •• class CDrawPublishLink
  1147. //==============================================================================
  1148.  
  1149. //------------------------------------------------------------------------------
  1150. //    • CDrawPublishLink::CDrawPublishLink
  1151. //------------------------------------------------------------------------------
  1152.  
  1153. CDrawPublishLink::CDrawPublishLink(XMPChangeID changeID, CDrawSelection *drawSelection) :
  1154.     FW_CPublishLink(changeID)
  1155. {
  1156.     fDrawSelection = drawSelection;
  1157.     fCollection = NULL;
  1158. }
  1159.  
  1160. //------------------------------------------------------------------------------
  1161. //    • CDrawPublishLink::~CDrawPublishLink
  1162. //------------------------------------------------------------------------------
  1163.  
  1164. CDrawPublishLink::~CDrawPublishLink()
  1165. {
  1166.     delete fCollection;
  1167. }
  1168.  
  1169. //------------------------------------------------------------------------------
  1170. //    • CDrawPublishLink::Publish
  1171. //------------------------------------------------------------------------------
  1172.  
  1173. void CDrawPublishLink::Publish()
  1174. {
  1175.     fCollection = new BC_TDynamicCollection<CBaseShape*, BC_CUnmanaged>(kChunkSize);
  1176.     
  1177.     BC_TCollectionActiveIterator<CBaseShape*> ite(*fDrawSelection->GetSelectionCollection());
  1178.     CBaseShape* shape;
  1179.     while (!ite.IsDone())
  1180.     {
  1181.         shape = *ite.CurrentItem();
  1182.         fCollection->Append(shape);
  1183.         shape->SetPublishLink(this);
  1184.         ite.Next();
  1185.     }
  1186. }
  1187.  
  1188. //------------------------------------------------------------------------------
  1189. //    • CDrawPublishLink::GetPublishFormat
  1190. //------------------------------------------------------------------------------
  1191.  
  1192. XMPValueType CDrawPublishLink::GetPublishFormat()
  1193. {    
  1194.     return kPublishFormat;
  1195. }
  1196.  
  1197. //------------------------------------------------------------------------------
  1198. //    • CDrawPublishLink::ExternalizeLinkContent
  1199. //------------------------------------------------------------------------------
  1200.  
  1201. void CDrawPublishLink::ExternalizeLinkContent(XMPStorageUnit* linkSU)
  1202. {    
  1203.     fDrawSelection->ExternalizeSelection(linkSU, NULL, kXMPCloneCopy);
  1204. }
  1205.  
  1206. //==============================================================================
  1207. //    •• class CDrawSubscribLink
  1208. //==============================================================================
  1209.  
  1210. //------------------------------------------------------------------------------
  1211. //    • CDrawSubscribLink::CDrawSubscribLink
  1212. //------------------------------------------------------------------------------
  1213.  
  1214. CDrawSubscribLink::CDrawSubscribLink(XMPLink *xmpLink, CDrawSelection *drawSelection) :
  1215.     FW_CSubscribLink(xmpLink)
  1216. {
  1217.     fDrawSelection = drawSelection;
  1218.     fCollection = NULL;
  1219. }
  1220.  
  1221. //------------------------------------------------------------------------------
  1222. //    • CDrawSubscribLink::~CDrawSubscribLink
  1223. //------------------------------------------------------------------------------
  1224.  
  1225. CDrawSubscribLink::~CDrawSubscribLink()
  1226. {
  1227.     delete fCollection;
  1228. }
  1229.  
  1230. //---------------------------------------------------------------------------------------
  1231. //    • CDrawSubscribLink::Subscrib
  1232. //---------------------------------------------------------------------------------------
  1233.  
  1234. void CDrawSubscribLink::Subscrib()
  1235. {
  1236.     fCollection = new BC_TDynamicCollection<CBaseShape*, BC_CUnmanaged>(kChunkSize);
  1237.     
  1238.     BC_TCollectionActiveIterator<CBaseShape*> ite(*fDrawSelection->GetSelectionCollection());
  1239.     CBaseShape* shape;
  1240.     while (!ite.IsDone())
  1241.     {
  1242.         shape = *ite.CurrentItem();
  1243.         fCollection->Append(shape);
  1244.         shape->SetSubscribLink(this);
  1245.         ite.Next();
  1246.     }
  1247. }
  1248.  
  1249.